//方位角测量js
import BaseMeasure from "./baseMeasure";
import '../prompt/prompt.css'
import Prompt from '../prompt/prompt.js'
/**
 * 方位角测量类
 * @class 
 * @augments BaseMeasure
 * @alias BaseMeasure.MeasureAzimutht 
 */
class MeasureAzimutht extends BaseMeasure {


  /**
    * 静态数组存储所有测量实例
    * @static
    */
  static instances = [];


  /**
   * 
   * @param {Cesium.Viewer} viewer 地图viewer对象 
   * @param {Object} opt 基础配置
   */
  constructor(viewer, opt) {
    super(viewer, opt);
    // 添加当前实例到静态数组
    MeasureAzimutht.instances.push(this);

    // 合并属性，保留原有属性并添加新属性
    this.attr = { ...(opt?.attr || {}), ...(opt?.style ? { style: opt.style } : {}) };



    /**
     * @property {Object} style 绘制样式（polyline），具体配置见{@link style};
     */
    this.style = opt.style || {};

    /**
     * @property {Cesium.Entity} polyline 线
     */
    this.polyline = null;
    this.floatLabel = null;

    /**
    * @property {Cesium.Cartesian3[]} positions 线坐标数组
    */
    this.positions = [];
    this.mtx = null;
    this.azimutht = null;
  }

  /**
   * 开始绘制
   * @param {Function} callback 绘制成功后回调函数
  */
  start(callback) {
    let that = this;
    this.state = "startCreate";
    if (!this.prompt && this.promptStyle.show) this.prompt = new Prompt(this.viewer, this.promptStyle);

    this.handler.setInputAction(function (evt) { //单击开始绘制
      let cartesian = that.getCatesian3FromPX(evt.position, that.viewer);
      if (!cartesian) return;
      if (that.positions.length == 2) {
        that.positions.pop();
        let point = that.createPoint(cartesian.clone());
        point.wz = 1;
        that.controlPoints.push(point);
        that.state = "endCreate";
        that.endCreate();
        if (callback) callback(that.azimutht);
      }

      if (!that.polyline) {
        that.polyline = that.createLine(that.positions, true);
        that.polyline.objId = that.objId;
        that.polyline.polyline.width = 6;
        // that.polyline.polyline.material = new Cesium.PolylineArrowMaterialProperty(Cesium.Color.YELLOW);
        that.polyline.polyline.material = Cesium.Color.YELLOW;
      }

      that.positions.push(cartesian);
      if (that.positions.length == 1) {
        that.mtx = Cesium.Transforms.eastNorthUpToFixedFrame(that.positions[0].clone());
        that.floatLabel = that.createLabel(cartesian, "");
        let point = that.createPoint(cartesian.clone());
        point.wz = 0;
        that.controlPoints.push(point);
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    this.handler.setInputAction(function (evt) {
      if (that.positions.length < 1) {
        that.prompt.update(evt.endPosition, "单击开始测量");
        return;
      }
      that.prompt.update(evt.endPosition, "单击结束");
      that.state = "creating";
      let cartesian = that.getCatesian3FromPX(evt.endPosition, that.viewer);
      if (!cartesian) return;

      if (that.positions.length < 2) {
        that.positions.push(cartesian.clone());
      } else {
        that.positions[1] = cartesian.clone();
      }

      if (that.floatLabel) {
        that.azimutht = that.getAzimuthtAndCenter(that.mtx, that.positions);
        that.floatLabel.label.text = "方位角：" + that.azimutht.toFixed(2);
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  }

  /**
   * 结束创建
   */
  endCreate() {
    let that = this;
    that.state = "endCreate";
    if (that.prompt) {
      that.prompt.destroy();
      that.prompt = null;
    }
    if (that.handler) {
      that.handler.destroy();
      that.handler = null;
    }
  }

  done() {
    if (this.state == "startCreate") {
      this.destroy();
    } else if (this.state == "startEdit" || this.state == "editing") {
      this.endEdit();
    } else {
      this.endCreate();
    }
  }

  setStyle(style) {
    if (!style) return;

    let material = this.getMaterial(style.material, style);
    this.entity.polyline.material = material;
    this.entity.polyline.clampToGround = Boolean(style.clampToGround);
    if (style.width) this.entity.polyline.width = style.width || 3;
    this.style = Object.assign(this.style, style);
  }
  /**
   * 
   * 开始编辑
   * @param {Function} callback 编辑成功后回调函数
   */
  startEdit(callback) {
    if (!((this.state == "endCrerate" || this.state == "endEdit") && this.polyline)) return;
    this.state = "startEdit";;
    if (!this.modifyHandler) this.modifyHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
    let that = this;
    for (let i = 0; i < that.controlPoints.length; i++) {
      let point = that.controlPoints[i];
      if (point) point.show = true;
    }
    this.modifyHandler.setInputAction(function (evt) {
      let pick = that.viewer.scene.pick(evt.position);
      if (Cesium.defined(pick) && pick.id) {
        if (!pick.id.objId)
          that.modifyPoint = pick.id;
        that.forbidDrawWorld(true);
      }
    }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
    this.modifyHandler.setInputAction(function (evt) {
      if (that.positions.length < 1 || !that.modifyPoint) return;
      let cartesian = that.getCatesian3FromPX(evt.endPosition, that.viewer);
      if (!cartesian) return;
      that.modifyPoint.position.setValue(cartesian.clone());
      if (that.modifyPoint.wz == 0) {
        that.floatLabel.position.setValue(cartesian.clone());
        that.mtx = Cesium.Transforms.eastNorthUpToFixedFrame(that.positions[0].clone());
      }
      that.positions[that.modifyPoint.wz] = cartesian.clone();
      that.azimutht = that.getAzimuthtAndCenter(that.mtx, that.positions);
      that.floatLabel.label.text = "方位角：" + that.azimutht.toFixed(2);
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    this.modifyHandler.setInputAction(function (evt) {
      if (!that.modifyPoint) return;
      that.modifyPoint = null;
      that.lastPosition = null;
      that.nextPosition = null;
      that.forbidDrawWorld(false);
      if (callback) callback();
      that.state = "endEdit";
    }, Cesium.ScreenSpaceEventType.LEFT_UP);
  }

  /**
   * 结束编辑
   */
  endEdit() {
    let that = this;
    this.state = "endEdit";;
    if (this.modifyHandler) {
      this.modifyHandler.destroy();
      this.modifyHandler = null;
    }
    for (let i = 0; i < that.controlPoints.length; i++) {
      let point = that.controlPoints[i];
      if (point) point.show = false;
    }
  }


  /**
  * 销毁
  */
  destroy() {
    // 从静态数组中移除当前实例
    const index = MeasureAzimutht.instances.indexOf(this);
    if (index > -1) {
      MeasureAzimutht.instances.splice(index, 1);
    }
    if (this.polyline) {
      this.viewer.entities.remove(this.polyline);
      this.polyline = null;
    }
    if (this.floatLabel) {
      this.viewer.entities.remove(this.floatLabel);
      this.floatLabel = null;
    }
    this.floatLable = null;

    if (this.handler) {
      this.handler.destroy();
      this.handler = null;
    }
    this.state = "no";
    if (this.prompt) {
      this.prompt.destroy();
      this.prompt = null;
    }
  }

  /**
     * 根据经纬度和方位角数据绘制测向线
     * @param {Array} data 数据数组，每个元素包含 startLon, startLat, endLon, endLat, azimutht
     * @param {Function} callback 绘制成功后回调函数
     */
  drawAzimuthtWithData(data, callback) {
    const ellipsoid = this.viewer.scene.globe.ellipsoid;
    for (let i = 0; i < data.length; i++) {
      const { startLon, startLat, endLon, endLat, azimutht } = data[i];
      const startCartesian = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(startLon, startLat));
      const endCartesian = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(endLon, endLat));

      this.positions = [startCartesian, endCartesian];
      this.mtx = Cesium.Transforms.eastNorthUpToFixedFrame(this.positions[0].clone());

      // if (!this.polyline) {
      this.polyline = this.createLine(this.positions, true);
      this.polyline.objId = this.objId;
      this.polyline.polyline.width = 6;
      this.polyline.polyline.material = Cesium.Color.YELLOW;
      // }

      this.floatLabel = this.createLabel(startCartesian, `方位角：${azimutht.toFixed(2)}`);

      const startPoint = this.createPoint(startCartesian.clone());
      startPoint.wz = 0;
      this.controlPoints.push(startPoint);

      const endPoint = this.createPoint(endCartesian.clone());
      endPoint.wz = 1;
      this.controlPoints.push(endPoint);

      this.state = "endCreate";
      this.endCreate();
    }
    if (callback) {
      callback();
    }
  }



  /**
      * 由geojson格式数据创建对象
      * @param {Object} data geojson格式数据
     */

  createByGeojson(data) {
    let { features } = data;

    for (let i = 0; i < features.length; i++) {
      let feature = features[i];
      const { properties, geometry } = feature;
      if (geometry.type == 'LineString') {
        // 创建新的测量实例并传递合并后的属性
        const measureInstance = new MeasureAzimutht(this.viewer, {
          style: this.style,
          // 直接将properties合并到attr，不使用formdata嵌套
          attr: { formdata: properties }
        });

        const entObj = {
          startLon: geometry.coordinates[0][0],
          startLat: geometry.coordinates[0][1],
          endLon: geometry.coordinates[1][0],
          endLat: geometry.coordinates[1][1],
          azimutht: properties.Heading
        };
        // 使用新实例绘制
        measureInstance.drawAzimuthtWithData([entObj]);
      }
    }
  }


  /**
     * 设置对象可见性
     * @param {Boolean} visible 是否可见
     */
  setVisible(visible) {
    if (this.polyline) {
      this.polyline.show = visible;
    }
    if (this.floatLabel) {
      this.floatLabel.show = visible;
    }
    this.controlPoints.forEach(point => {
      if (point) point.show = visible;
    });
  }




  /**
    * 静态方法：获取所有测量实例
    * @static
    * @returns {MeasureAzimutht[]} 所有方位角测量实例数组
    */
  getAllInstances() {
    return [...MeasureAzimutht.instances];
  }



  /**
     * 静态方法：根据attr属性字段获取测量实例
     * @static
     * @param {String} fieldName 属性字段名称
     * @param {*} [fieldValue] 属性值，若不填则默认按id查询
     * @returns {Object} {instance: MeasureAzimutht, index: Number} 找到的实例和索引
     */
  getInstanceByField(fieldName, fieldValue) {
    let result = { instance: null, index: -1 };
    if (!fieldValue) {
      // 如果未提供fieldValue，默认按attr.id查询
      for (let i = 0; i < MeasureAzimutht.instances.length; i++) {
        const instance = MeasureAzimutht.instances[i];
        if (instance.attr && instance.attr.id === fieldName) {
          result.instance = instance;
          result.index = i;
          break;
        }
      }
    } else {
      // 按字段名和值查询
      for (let i = 0; i < MeasureAzimutht.instances.length; i++) {
        const instance = MeasureAzimutht.instances[i];
        if (instance.attr && instance.attr[fieldName] === fieldValue) {
          result.instance = instance;
          result.index = i;
          break;
        }
      }
    }
    return result;
  }

/**
   * 静态方法：根据ID缩放至指定测量实例
   * @static
   * @param {String} id 要缩放至的实例ID
   * @param {Object} [options] Cesium飞行参数选项
   * @param {Number} [options.duration=3] 飞行持续时间(秒)
   * @param {Number} [options.offset] 视角偏移量
   * @returns {Boolean} 是否成功执行缩放
   */
  static zoomToInstanceById(id, options = {}) {
    // 获取指定ID的实例
    const result = this.getInstanceByField('id', id);
    if (!result.instance) {
      console.warn(`未找到ID为${id}的测量实例`);
      return false;
    }

    // 使用Cesium的flyTo方法缩放至对象
    if (result.instance.polyline) {
      result.instance.viewer.flyTo(result.instance.polyline, {
        duration: options.duration || 3,
        offset: options.offset || new Cesium.HeadingPitchRange(0, -0.5, 1000)
      });
      return true;
    }
    return false;
  }



}

export default MeasureAzimutht;

